import { bind, clear } from 'size-sensor';
import {
  requestAnimationFrame,
  cancelAnimationFrame,
  range,
  canvasStyle,
  randomNum,
} from './utils';
export default class NumAnimate {
  constructor(el) {
    this.el = el;
    this.text = [
      '0',
      '1',
      '2',
      '3',
      '4',
      '5',
      '6',
      '7',
      '8',
      '9',
      'A',
      'B',
      'C',
      'D',
      'E',
      'F',
      'G',
      'H',
      'I',
      'J',
      'K',
      'L',
      'M',
      'N',
      'O',
      'P',
      'Q',
      'R',
      'S',
      'T',
      'U',
      'V',
      'W',
      'X',
      'Y',
      'Z',
    ];

    this.c = {
      color: '6,211,229',
      zIndex: 1, // z-index
      opacity: 0.5, // opacity
    };
    this.canvas = this.newCanvas();
    this.context = this.canvas.getContext('2d');
    this.points = this.generatePoints();
    this.bindEvent();
    this.requestFrame(this.drawCanvas);
  }
  bindEvent() {
    bind(this.el, () => {
      this.canvas.width = this.el.clientWidth;
      this.canvas.height = this.el.clientHeight;
      this.points = this.generatePoints();
    });
  }
  newCanvas() {
    if (getComputedStyle(this.el).position === 'static') {
      this.el.style.position = 'relative';
    }
    const canvas = document.createElement('canvas'); // 画布
    canvas.style.cssText = canvasStyle(this.c);

    canvas.width = this.el.clientWidth;
    canvas.height = this.el.clientHeight;

    this.el.appendChild(canvas);
    return canvas;
  }
  generatePoints() {
    const width = this.canvas.width;
    const height = this.canvas.height;
    let r = width / 2; // 圆的半径
    let centerPoint = { x: width / 2, y: height / 2 };
    let charW = 20;
    let charH = 20;
    let x1 = 0;
    let points = [];
    let textLength = this.text.length;
    while (x1 < r / 3) {
      let x = centerPoint.x - x1;
      let angle = Math.acos(x / r);
      let h = r * Math.sin(angle) - 25; // -25是修正背景图不是规则的圆的问题
      let l = 0;
      let startY = centerPoint.y - h;
      while (l < 2 * h) {
        let y1 = startY + l;
        points.push({
          x: x1,
          y: y1,
          text: this.text[randomNum(0, textLength)],
        }); // 左侧的点
        points.push({
          x: x1 + (centerPoint.x - x1) * 2 - 10, // -10是修正背景图不是规则的圆的问题
          y: y1,
          text: this.text[randomNum(0, textLength)],
        }); // 参照y轴对称求右侧点
        l = l + charH;
      }
      x1 = x1 + charW;
    }
    return points;
  }
  drawCanvas() {
    const context = this.context;
    const width = this.canvas.width;
    const height = this.canvas.height;
    const points = this.points;
    context.clearRect(0, 0, width, height);
    // 遍历处理每一个点
    points.forEach((p, id) => {
      let opacityVal = randomNum(0, 5) / 10;
      context.fillStyle = `rgba(6, 211, 229, ${opacityVal})`;
      context.font = '20px Arial';
      context.fillText(p.text, p.x, p.y); // 绘制字符
    });
    this.requestFrame(this.drawCanvas);
  }
  requestFrame(func) {
    this.tid = requestAnimationFrame(() => func.call(this));
  }
  destroy() {
    // 清除事件
    clear(this.el);

    // 删除轮询
    cancelAnimationFrame(this.tid);

    // 删除 dom
    this.canvas.parentNode.removeChild(this.canvas);
  }
}
